import tkinter as tk
from tkinter import ttk, messagebox
import threading
import time
from src.types_pydantic.zlgcan_zuds_types import Uds_Request_Type
from datetime import datetime


class Uds_Display_Listview(tk.Frame):

    sendLabelFrame_height = 150
    sendLabelFrame_width = 150
    recvLabelFrame_height = 150
    recvLabelFrame_width = 150

    def __init__(self, master, rooter):
        super().__init__(master)
        self.rooter = rooter
        self.rooter.UDS_DISPLAY = self

        self.sendLabelFrame = tk.LabelFrame(
            self, height=self.sendLabelFrame_height, width=self.sendLabelFrame_width, text="uds发送回显")
        self.sendLabelFrame.grid(row=1, column=1, sticky=tk.NSEW)
        self.sendLabelFrameWidgetInit()
        pass

        self.recvLabelFrame = tk.LabelFrame(
            self, height=self.recvLabelFrame_height, width=self.recvLabelFrame_width, text='uds响应接收')
        self.recvLabelFrame.grid(row=1, column=2, sticky=tk.NSEW)
        self.recvLabelFrameWidgetInit()

    def sendLabelFrameWidgetInit(self):
        self.scrollbar_send = tk.Scrollbar(
            self.sendLabelFrame, orient=tk.VERTICAL)
        self.scrollbar_send.grid(row=2, column=2, sticky="ns")
        self.listSendUds = tk.Listbox(
            self.sendLabelFrame,
            font=("Arial", 12),
            height=20,
            width=50,
            yscrollcommand=self.scrollbar_send.set,
        )
        self.listSendUds.grid(row=2, column=1, sticky="nw")
        self.scrollbar_send.config(command=self.listSendUds.yview)

        self.bt_clear_sendUds = tk.Button(
            self.sendLabelFrame,
            text="清空",
            command=self.btn_click_cmd_clearListSendUds,
        )
        self.bt_clear_sendUds.grid(
            row=3, column=1, columnspan=2, padx=2, pady=2)
        pass

    def recvLabelFrameWidgetInit(self):
        self.scrollbar_recv = tk.Scrollbar(
            self.recvLabelFrame, orient=tk.VERTICAL)
        self.scrollbar_recv.grid(row=2, column=2, sticky="ns")
        self.listRecvUds = tk.Listbox(
            self.recvLabelFrame,
            font=("Arial", 12),
            height=20,
            width=50,
            yscrollcommand=self.scrollbar_recv.set,
        )
        self.listRecvUds.grid(row=2, column=1, sticky="nw")
        self.scrollbar_recv.config(command=self.listRecvUds.yview)

        self.bt_clear_recvUds = tk.Button(
            self.recvLabelFrame,
            text="清空",
            command=self.btn_click_cmd_clearListRevUds,
        )
        self.bt_clear_recvUds.grid(
            row=3, column=1, columnspan=2, padx=2, pady=2)
        pass

    def display_sendUds(self, uds_request: Uds_Request_Type):
        listView = self.listSendUds
        src_addr = uds_request.req_src_addr
        dst_addr = uds_request.req_dst_addr
        sid = uds_request.req_sid
        param_len = uds_request.req_param_len
        data = uds_request.req_data_1
        timestamp = f'{datetime.now():%Y-%m-%d %H:%M:%S}'

        listView.insert(tk.END, f'time:{timestamp},src:{hex(src_addr)},dst:{
                        hex(dst_addr)},sid:{hex(sid)},param_len:{hex(param_len)},param:{" ".join([hex(item) for item in data])}')
        listView.see(tk.END)

    def display_recvUds_positive(self, positive_resp):

        listView = self.listRecvUds
        listView.insert(
            tk.END, positive_resp)
        listView.see(tk.END)

    def display_recvUds_negative(self, negative_resp):
        listView = self.listRecvUds
        listView.insert(tk.END, negative_resp)
        listView.itemconfig(
            tk.END, background='pink')

    def btn_click_cmd_clearListSendUds(self):
        # messagebox.showinfo(message=' btn_click_cmd_clearListSendUds')
        self.listSendUds.delete(0, tk.END)

    def btn_click_cmd_clearListRevUds(self):
        # messagebox.showinfo(message=' btn_click_cmd_clearListRevUds')
        self.listRecvUds.delete(0, tk.END)


class Uds_Manual_Tab_Frame(tk.Frame):

    def __init__(self, master, rooter):
        super().__init__(master)
        self.ROOTER = rooter
        self.UDS_SERVE_FUNC = rooter.UDS_SERVE_FUNC

        # 初始化界面
        self.manualTabViewInit()

    def manualTabViewInit(self):
        self.displayFrame = Uds_Display_Listview(
            master=self, rooter=self.ROOTER)
        self.displayFrame.grid(row=1, column=1, sticky=tk.NSEW)

        self.manualSendFrame = tk.LabelFrame(
            self, height=150, width=800, text="uds信息设置(16进制)")
        self.manualSendFrame.grid(
            row=2, column=1, columnspan=2, sticky=tk.NSEW)
        self.manualSendFrameWidgetInit()

        self.sendMsgCycleFrame = tk.LabelFrame(
            self, height=50, width=800, text="循环周期发送")
        self.sendMsgCycleFrame.grid(
            row=3, column=1, columnspan=2, sticky=tk.NSEW)
        self.sendMsgCycleFrameWidgetInit()

    def manualSendFrameWidgetInit(self):
        # req_srcAddr输入
        self.req_srcAddr_label = tk.Label(self.manualSendFrame, text='req源地址')
        self.req_srcAddr_label.grid(row=1, column=1)
        self.req_srcAddr_entry = tk.Entry(self.manualSendFrame, width=10)
        self.req_srcAddr_entry.grid(row=1, column=2)
        self.req_srcAddr_entry.insert(0, '716')
        # req_dstAddr输入
        self.req_dstAddr_label = tk.Label(
            self.manualSendFrame, text='resp返回地址')
        self.req_dstAddr_label.grid(row=1, column=3)
        self.req_dstAddr_entry = tk.Entry(self.manualSendFrame, width=10)
        self.req_dstAddr_entry.grid(row=1, column=4)
        self.req_dstAddr_entry.insert(0, '796')
        pass
        # req sid 输入
        self.req_sid_label = tk.Label(
            self.manualSendFrame, text='服务号sid')
        self.req_sid_label.grid(row=1, column=5)
        self.req_sid_entry = tk.Entry(self.manualSendFrame, width=10)
        self.req_sid_entry.grid(row=1, column=6)
        self.req_sid_entry.insert(0, '22')

        # req_param_len设置
        self.req_param_len_label = tk.Label(
            self.manualSendFrame, text='发送参数长度')
        self.req_param_len_label.grid(row=1, column=7)
        self.req_param_len_entry = tk.Entry(self.manualSendFrame, width=10)
        self.req_param_len_entry.grid(row=1, column=8)
        self.req_param_len_entry.insert(0, '02')

        # req_data_1设置
        self.req_data_label = tk.Label(
            self.manualSendFrame, text='请求参数值(16进制,空格分隔)')
        self.req_data_label.grid(row=1, column=9)
        self.req_data_entry = tk.Entry(self.manualSendFrame, width=30)
        self.req_data_entry.grid(row=1, column=10)
        self.req_data_entry.insert(0, 'f1 90')

        # 单次发送按钮
        # command 是通过tester.work_flow来找到操作函数的，操作函数统一定义在WorkFlow中
        self.req_send_btn_once = tk.Button(
            self.manualSendFrame, text='单次发送', command=self.handle_send_once)
        self.req_send_btn_once.grid(row=2, column=1)

    def handle_send_once(self):
        from src.types_pydantic.zlgcan_zuds_types import Uds_Request_Type
        uds_request = Uds_Request_Type(req_src_addr=int(self.req_srcAddr_entry.get(), 16), req_dst_addr=int(self.req_dstAddr_entry.get(), 16),
                                       req_sid=int(self.req_sid_entry.get(), 16), req_param_len=int(self.req_param_len_entry.get(), 16),
                                       req_data_1=[
                                       int(item, 16) for item in self.req_data_entry.get().split()]
                                       )
        # self.TESTER.WORKFLOW.serveFunc.serve_default(uds_request)
        self.UDS_SERVE_FUNC.serve_default(uds_request)

    def sendMsgCycleFrameWidgetInit(self):
        self.send_cycle_time_label = tk.Label(
            self.sendMsgCycleFrame, text='发送周期时间(秒)')
        self.send_cycle_time_label.grid(row=1, column=1)
        self.send_cycle_time_entry = tk.Entry(self.sendMsgCycleFrame, width=10)
        self.send_cycle_time_entry.grid(row=1, column=2)
        self.send_cycle_time_entry.insert(0, '2')

        self.send_cycle_btn_start = tk.Button(
            self.sendMsgCycleFrame, text='开始发送', command=self.send_cycle_start)
        self.send_cycle_btn_start.grid(row=1, column=3)

        self.func_frame_radioButton_variable = tk.BooleanVar()
        self.func_frame_radioButton1 = tk.Radiobutton(
            self.sendMsgCycleFrame, text='循环关闭', variable=self.func_frame_radioButton_variable, value=False)
        self.func_frame_radioButton1.grid(
            row=1, column=4, padx=10, pady=2, sticky=tk.NSEW)

        self.func_frame_radioButton2 = tk.Radiobutton(
            self.sendMsgCycleFrame, text='循环启动', variable=self.func_frame_radioButton_variable, value=True)
        self.func_frame_radioButton2.grid(
            row=1, column=5, padx=10, pady=2, sticky=tk.NSEW)

    def send_cycle_start(self):
        cycle = float(self.send_cycle_time_entry.get())

        def wrapper():
            self.handle_send_once()
            while self.func_frame_radioButton_variable.get():
                time.sleep(cycle)
                self.handle_send_once()

            messagebox.showinfo('info', '退出循环...')

        th = threading.Thread(target=wrapper)
        th.start()
